require('babel-register');
process.on('uncaughtException', (err) => {
  console.log('错误:', err)
});
const axios = require('axios')
const express = require('express');
const ReactSSR = require('react-dom/server')
const net = require('net')
// const ReactSSR = require('react-dom/server')//server
const fs = require('fs')
const path = require('path')
const app = express();
const isDev = process.env.NODE_ENV === 'development';
const isStart = process.env.NODE_ENV === 'start';
const webpack = require("webpack");
const webpackMerge = require("webpack-merge");
const webpackBabelConfig = require('../build/webpack.config.babel');
// const webpackSsrConfig = require('../build/webpack.config.ssr');
// const webpackClientConfig = require('../build/webpack.config.client');
const webpackConfig = require('../build/config');
const MemoryFs = require('memory-fs')
const proxy = require('http-proxy-middleware');
function portIsOccupied(port) {
  // 创建服务并监听该端口
  var server = net.createServer().listen(port)

  server.on('listening', function () { // 执行这块代码说明端口未被占用
    server.close() // 关闭服务
    console.log('The port【' + port + '】 is available.') // 控制台输出信息
  })

  server.on('error', function (err) {
    if (err.code === 'EADDRINUSE') { // 端口已经被使用
      console.log('The port【' + port + '】 is occupied, please change other port.')
    }
  })
}

const getTemplate = () => {
  return new Promise((resolve, reject) => {
    // const { port } = clientConfig;
    const port = webpackConfig.ssrPort;
    //http去获取dev-server中的index.html
    axios.get(`http://localhost:${port}/public/index.html`)
      .then(res => {
        resolve(res.data)
      }).catch((err) => {
        reject(err);
      })
  })
}
if (!isDev) {//生产环境 直接到生成的dist目录读取文件
  if (isStart) {
    console.log('-------istart------dev ssr start');
    //增加dev middleware 开发 ssr启动
    // app.use(compression());
    let WebpackMergeConfig = webpackBabelConfig();
    // webpackConfig_merge = webpackConfig_merge[0]
    const compiler = webpack(WebpackMergeConfig);
    const options = {
      publicPath: WebpackMergeConfig.publicPath,
      noInfo: true,
      hot: true,
      stats: { color: true }
    };
    app.use(require("webpack-dev-middleware")(compiler, options));
    app.use(require("webpack-hot-middleware")(compiler));



    // function middlewareA(req, res, next) {
    //   console.log('middlewareA before next()');
    //   next();
    //   console.log('middlewareA after next()');
    // }
    // app.use(middlewareA);

    // app.use(express.static(path.join(__dirname, '../dist'), { maxAge: 86400000 * 30 }));
    // app.use("/public", express.static(path.resolve(__dirname, "../public")));

    // app.use('/public', express.static(path.join(__dirname, "../dist")))
    app.use("/public", express.static(path.resolve(__dirname, "../dist")));
    app.use(require('./util/ssr_middleware'));
    app.listen(3000, () => {
      // const { port } = server.address();
      console.log('----跑起来了！---', 3000);
      // console.info(`${color.green('Listened at port: ')}${color.cyan(port)}`);
    });
    return;
    //TODO:有问题的地方
  }
  const serverEntry = require('../dist/server-entry');
  //处理静态文件 凡是通过 /public访问的都是静态文件
  app.use('/public', express.static(path.join(__dirname, "../dist")))
  const template = fs.readFileSync(path.join(__dirname, '../dist/index.html'), 'utf8')

  app.get('*', function (req, res) {
    //ReactDOMServer.renderToString则是把React实例渲染成HTML标签
    let appString = ReactSSR.renderToString(serverEntry.default);
    //<!--App-->位置 就是我们渲染返回的结果插入的位置
    //约定template 来替换
    appString = template.replace('<!-- app -->', appString);
    console.log('appString', appString);
    //返回给客户端
    res.send(appString);
  })

  // const opn = require('opn');
  // // const address = require('address');
  // // const url = `http://${address.ip()}:${webpackConfig.ssrPort}`;
  // const url = `http://localhost:${webpackConfig.ssrPort}`;
  // opn(url)
} else {//开发环境 我们从内存中直接读取 减去了写到硬盘上的时间
  const devStatic = require('./util/dev-static');
  //8888clientPort  先启动 然后ssr启动
  devStatic(app);
}


// function portIsOccupied(port) {
//   const server = net.createServer().listen(port)
//   return new Promise((resolve, reject) => {
//     server.on('listening', () => {
//       // console.log(`the server is runnint on port ${port}`)
//       server.close()
//       resolve(portIsOccupied(port))
//     })

//     server.on('error', (err) => {
//       if (err.code === 'EADDRINUSE') {
//         console.log('----被炸用')
//         resolve(port);
//         const opn = require('opn');
//         // const address = require('address');
//         // const url = `http://${address.ip()}:${webpackConfig.ssrPort}`;
//         const url = `http://localhost:${webpackConfig.ssrPort}`;
//         opn(url)
//         //注意这句，如占用端口号+1
//         console.log(`this port ${port} is occupied.try another.`)
//       } else {
//         reject(err)
//       }
//     })
//   })

// }

app.listen(webpackConfig.ssrPort, function () {
  //所以为什么要build 之后再 run server了
  console.log(`server is listening on ${webpackConfig.ssrPort} port`);
})